// 
//  Copyright 2011  reda
// 
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
// 
//        http://www.apache.org/licenses/LICENSE-2.0
// 
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
using System;
using System.Collections.Generic;
using NHibernate.Validator.Constraints;
using System.Linq;

namespace ManiacMusicManager.Data.Core
{
	/// <summary>
	/// Représente une chanson
	/// </summary>
	public class Chanson : Entity
	{
		public Chanson ()
			: base()
		{
			this.Artistes		= new List<Artiste>();
			this.Albums			= new List<Album>();
			this.Genres			= new List<Genre>();
			this.Langages		= new List<Langage>();
			this.RelatedSongs	= new List<Chanson>();
			this.ChansonTags	= new List<string>();
		}
		
		#region Properties
		/// <summary>
		/// Titre de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual string Titre {
			get {
				return this.Name;
			}
			set {
				this.Name = value;
			}
		}
		
		/// <summary>
		/// Titre qui va servir pour effectuer un tri alphabétique de chansons
		/// </summary>
		[NotNullNotEmpty]
		public virtual string SortTitre {
			get;
			set;
		}
		
		/// <summary>
		/// Année de sortie de la chanson
		/// </summary>
		[NotNull]
		public virtual uint? AnneeDeSortie {
			get;
			set;
		}
		
		/// <summary>
		/// Lien wikipedia vers l'article traitant de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual string WikipediaURL {
			get;
			set;
		}
		
		/// <summary>
		/// Identifiant d'une vidéo youtube de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual string YoutubeId {
			get;
			set;
		}
		
		/// <summary>
		/// Indique si la chanson courante est une reprise par un autre artiste de la version originale
		/// </summary>
		[NotNull]
		public virtual bool? IsCover {
			get;
			set;
		}
		
		/// <summary>
		/// Indique si la chanson courante est une version acoustique de la version originale
		/// </summary>
		[NotNull]
		public virtual bool? IsAcoustic {
			get;
			set;
		}
		
		/// <summary>
		/// Indique si une chanson est une version instrumentale de l'originale
		/// </summary>
		[NotNull]
		public virtual bool? IsInstrumental {
			get;
			set;
		}
		
		/// <summary>
		/// Indique si la chanson courante est un remix de la version originale
		/// </summary>
		[NotNull]
		public virtual bool? IsRemix {
			get;
			set;
		}
		
		/// <summary>
		/// Indique si la chanson courante est une interprétation live de la version originale
		/// </summary>
		[NotNull]
		public virtual bool? IsLive {
			get;
			set;
		}
		
		/// <summary>
		/// Détails supplémentaires concernants le live (si toutefois la chanson courante en est un)
		/// </summary>
		public virtual string LiveDetails {
			get;
			set;
		}
		
		/// <summary>
		/// Paroles synchronisés de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual string SynchronizedLyrics {
			get;
			set;
		}
		
		/// <summary>
		/// Paroles non synchronizés de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual string UnsynchronizedLyrics {
			get;
			set;
		}
		
		/// <summary>
		/// Version originale de la chanson courante
		/// </summary>
		public virtual Chanson VersionOriginale {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des chanson qui sont en rapport avec la chanson courante
		/// </summary>
		public virtual IList<Chanson> RelatedSongs {
			get;
			set;
		}
		
		
		/// <summary>
		/// Liste des genres auquels appartient la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual IList<Genre> Genres {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des langages utilisé pour cette chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual IList<Langage> Langages {
			get;
			set;
		}
		
		/// <summary>
		/// Liste des albums sur lesquels figure la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual IEnumerable<Album> Albums {
			get;
			private set;
		}

		/// <summary>
		/// Liste des artistes ayant participé à la version courante de la chanson
		/// </summary>
		[NotNullNotEmpty]
		public virtual IEnumerable<Artiste> Artistes {
			get;
			private set;
		}
		
		/// <summary>
		/// Liste de mots clefs qui sont liés à la chanson courante
		/// </summary>
		public virtual IList<string> ChansonTags {
			get;
			set;
		}
		
		/// <summary>
		/// Identifiant MusicBrainz de l'artiste courant
		/// </summary>
		[NotNullNotEmpty]
		public virtual string MusicBrainzId {
			get;
			set;
		}
		#endregion
		

	#region Link/Unlink Album
		/// <summary>
		/// Lier avec un <see cref="Album"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void LinkAlbum(Album obj) {
			if(! this.Albums.Contains(obj))
				(this.Albums as IList<Album>).Add(obj);
			
			if(! obj.Chansons.Contains(this))
				(obj.Chansons as IList<Chanson>).Add(this);
		}
		
		/// <summary>
		/// Delier un <see cref="Album"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void UnlinkAlbum(Album obj) {
			if(this.Albums.Contains(obj))
				(this.Albums as IList<Album>).Remove(obj);
			
			if(obj.Chansons.Contains(this))
				(obj.Chansons as IList<Chanson>).Remove(this);
		}
	#endregion

	#region Link/Unlink Artiste
		/// <summary>
		/// Lier avec un <see cref="Artiste"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void LinkArtiste(Artiste obj) {
			if(! this.Artistes.Contains(obj))
				(this.Artistes as IList<Artiste>).Add(obj);
			
			if(! obj.Chansons.Contains(this))
				(obj.Chansons as IList<Chanson>).Add(this);
		}
		
		/// <summary>
		/// Delier un <see cref="Artiste"/>
		/// </summary>
		/// <param name="obj">
		/// Objet à lier
		/// </param>
		public virtual void UnlinkArtiste(Artiste obj) {
			if(this.Artistes.Contains(obj))
				(this.Artistes as IList<Artiste>).Remove(obj);
			
			if(obj.Chansons.Contains(this))
				(obj.Chansons as IList<Chanson>).Remove(this);
		}
	#endregion

	}
}

